////////////////////////////////////////////////////////////////////////////
//
//  Crytek Engine Source File.
//  Copyright (C), Crytek Studios, 2001-2005.
// -------------------------------------------------------------------------
//  File name:   HyperGraphDialog.h
//  Version:     v1.00
//  Created:     21/3/2005 by Timur.
//  Compilers:   Visual Studio.NET 2003
//  Description: 
// -------------------------------------------------------------------------
//  History: 24/09/2008 - Modified by Paulo Zaffari to add multi item 
//                        operations to the flowgraphs.
//
////////////////////////////////////////////////////////////////////////////

#ifndef __HyperGraphDialog_h__
#define __HyperGraphDialog_h__
#pragma once

#include "ToolbarDialog.h"
#include "HyperGraphView.h"
#include "Controls/PropertyCtrl.h"
#include "Controls/BreakPointsCtrl.h"

class CEntityObject;
class CPrefabObject;
class CFlowGraph;
class CFlowGraphSearchResultsCtrl;
class CFlowGraphSearchCtrl;
class CHyperGraphDialog;
class CFlowGraphProperties;
class CFlowGraphTokensCtrl;

//////////////////////////////////////////////////////////////////////////
class CHyperGraphsTreeCtrl : public CXTTreeCtrl, public IHyperGraphManagerListener
{
public:
	typedef std::vector<HTREEITEM>		TDTreeItems;

	CHyperGraphsTreeCtrl();
	~CHyperGraphsTreeCtrl();
	virtual BOOL Create(DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID);
	virtual void OnHyperGraphManagerEvent( EHyperGraphEvent event, IHyperGraph* pGraph, IHyperNode* pNode );
	void SetCurrentGraph( CHyperGraph *pGraph );
	void Reload();
	void SetIgnoreReloads(bool bIgnore) { m_bIgnoreReloads = bIgnore; }
	HTREEITEM GetTreeItem(CHyperGraph* pGraph);
	BOOL DeleteEntityItem(CEntityObject* pEntity, HTREEITEM& hAdjacentItem);
	BOOL DeleteNonEntityItem(CHyperGraph* pGraph, HTREEITEM& hAdjacentItem);
	void GetSelectedItems(TDTreeItems& rchSelectedTreeItems);
	
protected:
	DECLARE_MESSAGE_MAP()
	afx_msg BOOL OnEraseBkgnd(CDC* pDC);

	void OnObjectEvent( CBaseObject *pObject,int nEvent );
	CHyperGraph *m_pCurrentGraph;
	bool m_bIgnoreReloads;
	CImageList m_imageList;

	std::map<CEntityObject*,HTREEITEM> m_mapEntityToItem;
	std::map<CPrefabObject*, HTREEITEM> m_mapPrefabToItem;
};

//////////////////////////////////////////////////////////////////////////
class CHyperGraphComponentsReportCtrl : public CXTPReportControl
{
	DECLARE_MESSAGE_MAP()
public:
	CHyperGraphComponentsReportCtrl();
	~CHyperGraphComponentsReportCtrl();

	CImageList* CreateDragImage(CXTPReportRow* pRow);
	void SetDialog (CHyperGraphDialog *pDialog) { m_pDialog = pDialog; }
	void Reload();
	void SetComponentFilterMask(uint32 mask) { m_mask = mask; }
	void SetSearchKeyword(const CString& keyword);

protected:
	afx_msg void OnLButtonDown( UINT nFlags, CPoint point );
	afx_msg void OnLButtonUp( UINT nFlags, CPoint point );
	afx_msg void OnMouseMove( UINT nFlags, CPoint point );
	afx_msg void OnCaptureChanged( CWnd* );
	afx_msg void OnRButtonDown(UINT nFlags, CPoint point);
	afx_msg void OnReportColumnRClick( NMHDR* pNotifyStruct, LRESULT* result );
	afx_msg void OnReportItemDblClick( NMHDR* pNotifyStruct, LRESULT* result );

	afx_msg void OnDestroy();

	bool IsHeaderVisible();
	void SetHeaderVisible(bool bVisible);

protected:
	CImageList m_imageList;
	CHyperGraphDialog* m_pDialog;
	uint32 m_mask;
	CPoint m_ptDrag;
	bool m_bDragging;
	bool m_bDragEx;
	bool m_bHeaderVisible;
	std::vector<CString> m_searchKeywords;
};

//////////////////////////////////////////////////////////////////////////
//
// Main Dialog for HyperGraph.
//
//////////////////////////////////////////////////////////////////////////
class CHyperGraphDialog : public CXTPFrameWnd, public IEditorNotifyListener, public IHyperGraphManagerListener
{
	DECLARE_DYNCREATE(CHyperGraphDialog)	
public:
	typedef std::vector<HTREEITEM>		TDTreeItems;

	static void RegisterViewClass();

	CHyperGraphDialog();
	~CHyperGraphDialog();

	BOOL Create( DWORD dwStyle,const RECT& rect,CWnd* pParentWnd );

	// Return pointer to the hyper graph view.
	CHyperGraphView* GetGraphView() { return &m_view; };

	CFlowGraphSearchCtrl* GetSearchControl() const { return m_pSearchOptionsView; }

	void SetGraph( CHyperGraph* pGraph );

	void OnViewSelectionChange();
	void ShowResultsPane(bool bShow=true, bool bFocus=true);
	void UpdateGraphProperties(CHyperGraph* pGraph);
	// Delete item from treeview ctrl
	void DeleteItem(CEntityObject* pEntity);
  
	void OnComponentBeginDrag(CXTPReportRow* pRow, CPoint pt);

	void ReloadBreakpoints(){m_breakpointsTreeCtrl.FillBreakpoints();};
	void ClearBreakpoints(){m_breakpointsTreeCtrl.DeleteAllItems();};
	void ReloadGraphs(){m_graphsTreeCtrl.Reload();};
	void ReloadComponents(){m_componentsReportCtrl.Reload();};

	enum { IDD = IDD_TRACKVIEWDIALOG };

protected:
	DECLARE_MESSAGE_MAP()

	virtual void OnOK() {};
	virtual void OnCancel() {};

	virtual BOOL PreTranslateMessage(MSG* pMsg);
	virtual BOOL OnInitDialog();
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
	virtual void PostNcDestroy();
	afx_msg void OnMouseMove(UINT nFlags, CPoint point);
	afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
	afx_msg void OnSize(UINT nType, int cx, int cy);
	afx_msg void OnSetFocus(CWnd* pOldWnd);
	afx_msg void OnDestroy();
	afx_msg void OnClose();
	afx_msg void OnPaint();
	afx_msg BOOL OnEraseBkgnd(CDC* pDC);
	afx_msg void OnFileNew();
	afx_msg void OnFileOpen();
	afx_msg void OnFileSave();
	afx_msg void OnFileSaveAs();
	afx_msg void OnFileNewAction();
	afx_msg void OnFileNewUIAction();
	afx_msg void OnFileNewMatFXGraph();
	afx_msg void OnFileNewGlobalFGModule();
	afx_msg void OnFileNewLevelFGModule();
	afx_msg void OnFileImport();
	afx_msg void OnFileExportSelection();
	afx_msg void OnEditGraphTokens();
	afx_msg void OnEditModuleInputsOutputs();

	afx_msg LRESULT OnDockingPaneNotify(WPARAM wParam, LPARAM lParam);
	afx_msg void OnGraphsRightClick(NMHDR* pNMHDR, LRESULT* pResult);
	afx_msg void OnGraphsDblClick(NMHDR* pNMHDR, LRESULT* pResult);
	afx_msg void OnGraphsSelChanged(NMHDR* pNMHDR, LRESULT* pResult);
	afx_msg void OnBreakpointsRightClick(NMHDR* pNMHDR, LRESULT* pResult);
	afx_msg void OnBreakpointsClick(NMHDR* pNMHDR, LRESULT* pResult);
	afx_msg void OnPlay();
	afx_msg void OnStop();
	afx_msg void OnToggleDebug();
	afx_msg void OnEraseDebug();
	afx_msg void OnPause();
	afx_msg void OnStep();
	afx_msg void OnUpdatePlay( CCmdUI *pCmdUI );
	afx_msg void OnUpdateStep( CCmdUI *pCmdUI );
	afx_msg void OnUpdateDebug( CCmdUI *pCmdUI );
	afx_msg void OnFind();
	afx_msg BOOL OnComponentsViewToggle( UINT nID );
	afx_msg void OnComponentsViewUpdate( CCmdUI *pCmdUI );

	afx_msg BOOL OnToggleBar( UINT nID );
	afx_msg void OnUpdateControlBar(CCmdUI* pCmdUI);
	afx_msg BOOL OnMultiPlayerViewToggle (UINT nID);
	afx_msg void OnMultiPlayerViewUpdate (CCmdUI* pCmdUI);
	afx_msg int  OnCreateControl(LPCREATECONTROLSTRUCT lpCreateControl); 
	afx_msg int  OnCreateCommandBar(LPCREATEBARSTRUCT lpCreatePopup);
	afx_msg void OnNavListBoxControlSelChange(NMHDR* pNMHDR, LRESULT* pRes);
	afx_msg void OnNavListBoxControlPopup(NMHDR* pNMHDR, LRESULT* pRes);
	afx_msg void OnUpdateNav(CCmdUI* pCmdUI);
	afx_msg void OnNavForward();
	afx_msg void OnNavBack();
	afx_msg void OnCustomize();
	afx_msg void OnExportShortcuts();
	afx_msg void OnImportShortcuts();
	afx_msg void OnComponentSearchEditChange();

	virtual BOOL OnCmdMsg(UINT nID, int nCode, void* pExtra,AFX_CMDHANDLERINFO* pHandlerInfo);

	void ClearGraph();
	void NewGraph();
	void CreateRightPane();
	void CreateLeftPane();
	CXTPDockingPaneManager* GetDockingPaneManager() { return &m_paneManager; }

	void GraphUpdateEnable(CFlowGraph* pFlowGraph, HTREEITEM hItem);
	void EnableItems(HTREEITEM hItem, bool bEnable, bool bRecurse);
	void RenameItems(HTREEITEM hItem, CString& newGroupName, bool bRecurse);

	void UpdateComponentPaneTitle();

	// Called by the editor to notify the listener about the specified event.
	void OnEditorNotifyEvent( EEditorNotifyEvent event );

	// Called by hypergraph manager (need this for nav back/forward)
	virtual void OnHyperGraphManagerEvent( EHyperGraphEvent event, IHyperGraph* pGraph, IHyperNode* pNode );
	
	void UpdateNavHistory();
	void UpdateTitle(CHyperGraph* pGraph);


	// Creates the right click context menu based on the currently selected items.
	// The current policy will make the menu have only the menu items that are common
	// to the entire selection.
	// OBS: renaming is only allowed for single selections.
	bool CreateContextMenu(CMenu& roMenu,TDTreeItems& rchSelectedItems);

	// This function will take the result of the menu and will process its
	// results applying the appropriate changes.
	void ProcessMenu(int nMenuOption, TDTreeItems& rchSelectedItems);

	bool CreateBreakpointContextMenu(CMenu& roMenu,HTREEITEM hItem);
	void ProcessBreakpointMenu(int nMenuOption, HTREEITEM hItem);

	//////////////////////////////////////////////////////////////////////////
	// This set of functions is used to help determining which menu items will
	// be available. Their usage is not 100% efficient, still, they improved
	// the readability of the code and thus made refactoring a lot easier.
	bool IsAnEntityFolderOrSubFolder(HTREEITEM hSelectedItem);	
	bool IsAnEntitySubFolder(HTREEITEM hSelectedItem);
	// As both values, true or false would have interpretations,
	// we need to add another flag identifying if the result 
	bool IsGraphEnabled(HTREEITEM hSelectedItem,bool &boIsEnabled);
	bool IsOwnedByAnEntity(HTREEITEM hSelectedItem);
	bool IsAssociatedToFlowGraph(HTREEITEM hSelectedItem);
	bool IsGraphType(HTREEITEM hSelectedItem, IFlowGraph::EFlowGraphType type);
private:
	void NewFGModule(bool bGlobal=true);

	CHyperGraphView m_view;

	CXTPTaskPanel m_wndTaskPanel;
	CPropertyCtrl m_wndProps;
	CXTPStatusBar m_statusBar;

	CImageList m_treeImageList;
	CHyperGraphsTreeCtrl m_graphsTreeCtrl;
	CBreakpointsTreeCtrl m_breakpointsTreeCtrl;
	CXTPTaskPanel m_componentsTaskPanel;
	CHyperGraphComponentsReportCtrl m_componentsReportCtrl;
	CColorCtrl<CEdit> m_componentSearchEdit;
	CImageList *m_pDragImage;
	CString m_dragNodeClass;
	CFlowGraphSearchResultsCtrl *m_pSearchResultsCtrl;
	CFlowGraphSearchCtrl *m_pSearchOptionsView;
	CFlowGraphProperties *m_pGraphProperties;
	CFlowGraphTokensCtrl *m_pGraphTokens;

	CXTPTaskPanelGroup* m_pPropertiesFolder;
	CXTPTaskPanelGroupItem *m_pPropertiesItem;
	
	
	CXTPDockingPaneManager m_paneManager;
	uint32 m_componentsViewMask;

	std::list<CHyperGraph*> m_graphList;
	std::list<CHyperGraph*>::iterator m_graphIterCur;
	CHyperGraph* m_pNavGraph;
	IFlowGraphDebuggerConstPtr m_pFlowGraphDebugger;
};

#endif // __HyperGraphDialog_h__
